package com.ahu.aspect;

import com.ahu.annotation.ParamCheck;
import com.ahu.util.RequestException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * Created by qx on 2018/3/8.
 */

@Aspect
@Component
public class CheckAspect {
//    static long startTime = System.currentTimeMillis();
    private final static org.slf4j.Logger logger= LoggerFactory.getLogger(CheckAspect.class);
    @Pointcut("execution(* com.ahu.controller..*.*(..))")
    public void check(){

    }

    @Before("check()")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes attributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request=attributes.getRequest();
        logger.info("请求开始-------------------------------------------------------");
        logger.info("请求的IP地址：" + request.getRemoteAddr());
        logger.info("请求地址：" + request.getRequestURL().toString());
        logger.info("请求类型：" + request.getMethod());
        logger.info("访问类及方法：" + joinPoint.getSignature().getDeclaringTypeName() + "/" + joinPoint.getSignature().getName());
        logger.info("请求参数：" + Arrays.toString(joinPoint.getArgs()));

    }
    @Around("check()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        Object result = null;
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        if (parameterAnnotations == null || parameterAnnotations.length == 0){
            long startTime = System.currentTimeMillis();
            result = pjp.proceed();
            logger.info("返回值：" + result);
            logger.info("请求完成");
            logger.info("耗时：" + (System.currentTimeMillis()-startTime));
            return result;
        }
        for(int i = 0; i<parameterAnnotations.length; i++){
            int length = parameterAnnotations[i].length;
            for(int j=0; j<length; j++){
                if (parameterAnnotations[i][j] != null || parameterAnnotations[i][j] instanceof ParamCheck ||
                        ((ParamCheck) parameterAnnotations[i][j]).notNull()){
                    Object[] args = pjp.getArgs();
                    CheckAspect.checkNull(args[0], "idCard");
                    CheckAspect.checkNull(args[1], "number");
                    break;
                }
            }
        }
        long startTime = System.currentTimeMillis();
        result = pjp.proceed();

        logger.info("返回值：" + result);
        logger.info("请求完成");
        logger.info("耗时：" + (System.currentTimeMillis()-startTime));
        return result;

    }
//
//    @AfterReturning(returning = "object",pointcut="check()")
//    public void doAfterReturning(Object object) throws Throwable{
//        logger.info("返回值：" + object);
//        logger.info("请求完成");
//        logger.info("耗时：" + (System.currentTimeMillis()-startTime));
//    }

    /**
     * List 检测
     * @param list  List
     * @param <T>   List类型
     */
    public static  <T> void checkList(List<T> list, String exceptionName){
        if (list==null) {
            throw new RequestException(exceptionName + " 为 null");
        }
        if (list.isEmpty()) {
            throw new RequestException(exceptionName + " 为 empty");
        }
    }

    /**
     * null 检测
     * @param parameter     参数
     * @param <T>           参数类型
     */
    public static <T> void checkNull(T parameter,String exceptionName){
        if (parameter==null) {
            throw new RequestException(exceptionName + " 为 null");
        }
    }

}
